package com.ccrfid.rmc6.service.alarm;

import com.ccrfid.rmc6.appconfig.exception.pojo.AppException;
import com.ccrfid.rmc6.appconfig.exception.pojo.CustomErrors;
import com.ccrfid.rmc6.entity.alarm.AlarmNotifyRecordEntity;
import com.ccrfid.rmc6.entity.alarm.AlarmNotifyRecordView;
import com.ccrfid.rmc6.entity.alarm.AlarmRecordEntity;
import com.ccrfid.rmc6.entity.device.CardEntity;
import com.ccrfid.rmc6.entity.sys.AccountEntity;
import com.ccrfid.rmc6.pojo.Constants;
import com.ccrfid.rmc6.pojo.dto.alarm.AlarmNotifyRecordCountDto;
import com.ccrfid.rmc6.repository.alarm.AlarmNotifyRecordRepository;
import com.ccrfid.rmc6.repository.alarm.AlarmNotifyRecordVeiwRepository;
import com.ccrfid.rmc6.repository.alarm.AlarmRecordRepository;
import com.ccrfid.rmc6.repository.device.CardRepository;
import com.ccrfid.rmc6.repository.search.SearchCriteria;
import com.ccrfid.rmc6.repository.sys.AccountRepository;
import com.ccrfid.rmc6.service.amq.MqMsgProducer;
import com.ccrfid.rmc6.util.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import javax.ws.rs.core.Response;
import java.sql.Timestamp;
import java.util.List;

@Service
@Transactional
public class AlarmRecordServiceImpl implements AlarmRecordService {
    private static final Logger logger = LoggerFactory.getLogger(AlarmRecordServiceImpl.class);

    @Autowired
    private AlarmRecordRepository alarmRecordRepository;
    @Autowired
    private AlarmNotifyRecordRepository alarmNotifyRecordRepository;
    @Autowired
    private AlarmNotifyRecordVeiwRepository alarmNotifyRecordVeiwRepository;
    @Autowired
    private AccountRepository accountRepository;
    @Autowired
    private CardRepository cardRepository;
    @Autowired
    private MqMsgProducer mqMsgProducer;

    @Override
    public Page<AlarmRecordEntity> getAlarmRecords(SearchCriteria criteria, Pageable pageable) {
        return alarmRecordRepository.search(criteria, pageable);
    }

    @Override
    public Page<AlarmNotifyRecordView> getPersonalAlarmNotifyRecords(SearchCriteria criteria, Pageable pageable) {
        return alarmNotifyRecordVeiwRepository.search(criteria, pageable);
    }

    @Override
    public AlarmRecordEntity getAlarmCallRecordInMinute(Long cardNumber, Long time) {
        return alarmRecordRepository.getTopByAlarmTypeAndCardNumberAndAlarmTimeAfter(
                Constants.ALARM_TYPE.CALL.id, cardNumber, new Timestamp(time - 60 * 1000));
    }

    @Override
    public AlarmRecordEntity getAlarmCutoffRecordUnClosed(Long cardNumber) {
        return alarmRecordRepository.getTopByAlarmTypeAndCardNumberAndClosed(
                Constants.ALARM_TYPE.CUTOFF.id, cardNumber, 0);
    }

    @Override
    public AlarmRecordEntity getAlarmLowpowerRecordUnClosed(Long cardNumber) {
        return alarmRecordRepository.getTopByAlarmTypeAndCardNumberAndClosed(
                Constants.ALARM_TYPE.LOWPOWER.id, cardNumber, 0);
    }

    @Override
    public AlarmRecordEntity getAlarmOfflineRecordUnClosed(Long cardNumber) {
        return alarmRecordRepository.getTopByAlarmTypeAndCardNumberAndClosed(
                Constants.ALARM_TYPE.OFFLINE.id, cardNumber, 0);
    }

    @Override
    public AlarmRecordEntity createAlarmRecord(AlarmRecordEntity entity) {
        CardEntity cardEntity = cardRepository.getByCardNumber(entity.getCardNumber());
        if(cardEntity != null && cardEntity.getHexNumber() != null){
            entity.setHexNumber(cardEntity.getHexNumber());
        }
        AlarmRecordEntity alarmRecordEntity = alarmRecordRepository.save(entity);
        //分发告警消息到MQ
        mqMsgProducer.send2Topic("ws_alarm_msg", JsonUtil.INSTANCE.writeValueAsString(alarmRecordEntity));
        return alarmRecordEntity;
    }

    @Override
    public AlarmRecordEntity updateAlarmRecord(AlarmRecordEntity entity) {
        AlarmRecordEntity alarmRecordEntity = alarmRecordRepository.save(entity);
        //分发告警消息到MQ
        mqMsgProducer.send2Topic("ws_alarm_msg", JsonUtil.INSTANCE.writeValueAsString(alarmRecordEntity));
        return alarmRecordEntity;
    }

    @Override
    public Boolean markReadPersonalAlarmRecord(Long alarmNotifyRecordId) throws AppException {
        if (!alarmNotifyRecordRepository.existsById(alarmNotifyRecordId)) {
            throw new AppException(Response.Status.NOT_FOUND.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        AlarmNotifyRecordEntity alarmNotifyRecord = alarmNotifyRecordRepository.getById(alarmNotifyRecordId);
        alarmNotifyRecord.setRead(1);
        alarmNotifyRecordRepository.save(alarmNotifyRecord);



        return true;
    }

    @Override
    public Boolean markReadPersonalAlarmRecords(List<Long> idList) throws AppException {
        if (idList == null) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.param_is_null.getCode(), CustomErrors.param_is_null.getReason(), "");
        }
        for (Long id : idList) {
            AlarmNotifyRecordEntity alarmNotifyRecord = alarmNotifyRecordRepository.getById(id);
            if (alarmNotifyRecord != null) {
                alarmNotifyRecord.setRead(1);
                alarmNotifyRecordRepository.save(alarmNotifyRecord);
            }
        }
        return true;
    }

    @Override
    public Boolean markReadAllPersonalAlarmRecords(String userAccount) {
        AccountEntity accountEntity = accountRepository.getByUserAccount(userAccount);
        if (accountEntity != null && accountEntity.getPersonnelId() != null) {
            alarmNotifyRecordRepository.markReadAllAlarmNotifyRecords(accountEntity.getPersonnelId());
        }
        return true;
    }

    @Override
    public AlarmNotifyRecordCountDto getAlarmNotifyRecordCount(Long notifyPersonnelId){
        AlarmNotifyRecordCountDto alarmNotifyRecordCountDto = new AlarmNotifyRecordCountDto();
        //已读数
        int isReaded = alarmNotifyRecordRepository.getAllByNotifyPersonnelIdAndRead(notifyPersonnelId,1).size();
        //未读数
        int noRead = alarmNotifyRecordRepository.getAllByNotifyPersonnelIdAndRead(notifyPersonnelId,0).size();
        //总数
        int totalCount = alarmNotifyRecordRepository.getAllByNotifyPersonnelId(notifyPersonnelId).size();
        alarmNotifyRecordCountDto.setTotalCount(totalCount);
        alarmNotifyRecordCountDto.setIsReaded(isReaded);
        alarmNotifyRecordCountDto.setNoRead(noRead);

        return alarmNotifyRecordCountDto;
    }

    @Override
    public Integer getViolation(Long noyifyPersonnelId, List<Integer> alarmTypeList, Integer read) {
        return alarmNotifyRecordVeiwRepository.countAllByNotifyPersonnelIdAndAlarmTypeInAndRead(noyifyPersonnelId, alarmTypeList, 0);
    }

    @Override
    public AlarmRecordEntity getAlarmVitalSignRecordUnClosed(Long cardNumber, Integer alarmType) {
        return alarmRecordRepository.getTopByAlarmTypeAndCardNumberAndClosed(
                alarmType, cardNumber, 0);
    }
}
